package com.jrx.anytxn.transaction.job.customer.step;

import com.alibaba.fastjson.JSONObject;
import com.jrx.anytxn.common.constant.CommonContants;
import com.jrx.anytxn.common.data.TxnRespCode;
import com.jrx.anytxn.common.uitl.DateUtils;
import com.jrx.anytxn.common.uitl.JsonUtils;
import com.jrx.anytxn.customer.entity.CmCustomerContactInfo;
import com.jrx.anytxn.customer.entity.CmCustomerExtInfo;
import com.jrx.anytxn.customer.entity.CmCustomerFirstLevel;
import com.jrx.anytxn.customer.entity.CmCustomerLimitInfo;
import com.jrx.anytxn.customer.entity.CmCustomerSecondLevel;
import com.jrx.anytxn.customer.entity.CmLimitAdjustLog;
import com.jrx.anytxn.customer.entity.CmLimitChangeLog;
import com.jrx.anytxn.customer.mapper.ext.ExtCmCustomerContactInfoMapper;
import com.jrx.anytxn.customer.mapper.ext.ExtCmCustomerExtInfoMapper;
import com.jrx.anytxn.customer.mapper.ext.ExtCmCustomerFirstLevelMapper;
import com.jrx.anytxn.customer.mapper.ext.ExtCmCustomerSecondLevelMapper;
import com.jrx.anytxn.customer.mapper.ext.ExtCmLimitAdjustLogMapper;
import com.jrx.anytxn.customer.service.ICustomerLimitInfoService;
import com.jrx.anytxn.feign.api.request.LimitRenewRequest;
import com.jrx.anytxn.feign.api.response.LimitRenewResponse;
import com.jrx.anytxn.feign.api.service.IUserApiService;
import com.jrx.anytxn.feign.gateway.bean.ApiResponse;
import com.jrx.anytxn.param.entity.PrCreditLimitMapping;
import com.jrx.anytxn.param.entity.PrOrganizationTable;
import com.jrx.anytxn.param.mapper.ext.ExtPrCreditLimitMappingMapper;
import com.jrx.anytxn.param.service.system.IOrganizationTableService;
import com.jrx.anytxn.param.utils.BizTypeProducts;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import com.jrx.anytxn.transaction.entity.TlPaymentLog;
import com.jrx.anytxn.transaction.mapper.ext.ExtAmDelinquencyInfoMapper;
import com.jrx.anytxn.transaction.mapper.ext.ExtAmLoanAccountInfoMapper;
import com.jrx.anytxn.transaction.mapper.ext.ExtTlPaymentLogMapper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @comment: 额度续期Processor
 * @author: liuzb
 * @date: 2022/10/19 10:00
 */
@Service
public class LimitRenewalProcessor implements ItemProcessor<CmCustomerLimitInfo, CmCustomerLimitInfo> {

    private static final Logger logger = LoggerFactory.getLogger(LimitRenewalProcessor.class);

    @Autowired
    private IUserApiService iUserApiService;
    @Autowired
    private IOrganizationTableService organizationTableService;
    @Resource
    private ExtPrCreditLimitMappingMapper extPrCreditLimitMappingMapper;
    @Resource
    private ExtCmCustomerSecondLevelMapper extCmCustomerSecondLevelMapper;
    @Resource
    private ExtCmCustomerFirstLevelMapper extCmCustomerFirstLevelMapper;
    @Resource
    private ExtCmLimitAdjustLogMapper extCmLimitAdjustLogMapper;
    @Resource
    private ExtAmLoanAccountInfoMapper extAmLoanAccountInfoMapper;
    @Resource
    private ExtAmDelinquencyInfoMapper extAmDelinquencyInfoMapper;
    @Resource
    private ExtTlPaymentLogMapper extTlPaymentLogMapper;
    @Resource
    private ExtCmCustomerContactInfoMapper extCmCustomerContactInfoMapper;
    @Resource
    private ICustomerLimitInfoService iCustomerLimitInfoService;
    @Resource
    private ExtCmCustomerExtInfoMapper extCmCustomerExtInfoMapper;

    @Override
    public CmCustomerLimitInfo process(CmCustomerLimitInfo customerLimit) throws Exception {

        String organizationId = customerLimit.getOrganizationId();
        String channel = customerLimit.getChannel();
        String tenantId = customerLimit.getTenantId();
        String limitId = customerLimit.getLimitId();
        String customerId = customerLimit.getCustomerId();
        Date limitExpiryDate = customerLimit.getLimitExpiryDate();
        String expiryDate = DateUtils.format(limitExpiryDate);
        CmCustomerFirstLevel firstLevel = extCmCustomerFirstLevelMapper.selectFirstLevelByOrgIdAndCusId(customerId, organizationId, tenantId);
        // 逾期客户不跑风控
        if (StringUtils.isNotBlank(firstLevel.getBlockCode())) {
            return customerLimit;
        }
        String productId = "";
        List<PrCreditLimitMapping> mappings = extPrCreditLimitMappingMapper.selectLimitListIdAndTenantId(organizationId, channel, tenantId, limitId);
        if (CollectionUtils.isNotEmpty(mappings)) {
            Optional<PrCreditLimitMapping> min = mappings.stream().min(Comparator.comparing(PrCreditLimitMapping::getProductId));
            if (min.isPresent()) {
                productId = min.get().getProductId();
            }
        }
        if (StringUtils.isBlank(productId)) {
            logger.warn("客户id：{},额度id：{}没有对应的产品编号", customerId, limitId);
            return null;
        }
        // 没有用信的用户也不跑风控和发送短信
        // 获取用户"首笔贷款额度信息"
        CmLimitChangeLog firstLimitInfo = iCustomerLimitInfoService.queryFirstLimitChangeLog(tenantId, customerId, Collections.singletonList(productId));
        if(Objects.isNull(firstLimitInfo) || StringUtils.isBlank(firstLimitInfo.getEtlLoanId())){
            logger.info("该用户{}没有用信记录，不必跑风控", customerId);
            return null;
        }
        logger.info("客户id：{},产品编号：{},额度有效期：{}", customerId, productId, expiryDate);
        CmCustomerSecondLevel secondLevel = extCmCustomerSecondLevelMapper.selectByCustomerIdAndChannel(customerId, channel, tenantId);
        List<CmLimitAdjustLog> cmLimitAdjustLogs = extCmLimitAdjustLogMapper.selectByTenIdAndCusId(tenantId, customerId);
        PrOrganizationTable org = organizationTableService.findByOrgIdForBatch(TransBizConstant.DEFAULT_ORG_ID);
        // 修改客户客群
        List<CmCustomerExtInfo> cmCustomerExtInfos = extCmCustomerExtInfoMapper.queryCustomerExtInfos(customerId, tenantId, BizTypeProducts.getSymbolProductId(productId));
        if (CollectionUtils.isNotEmpty(cmCustomerExtInfos)) {
            secondLevel.setCustomerGroup(cmCustomerExtInfos.get(0).getCustomerGroup());
        }

        // 当前业务日期
        Date today = org.getNextProcessingDate();

        BigDecimal limitAmount = customerLimit.getLimitAmount();
        LimitRenewRequest limitReq = new LimitRenewRequest();
        limitReq.setReqSeq(customerLimit.getSeqNo());
        limitReq.setCustomerId(customerId);
        limitReq.setCustName(firstLevel.getChineseName());
        limitReq.setOrigCreditLimit(limitAmount);
        limitReq.setOrigExpiryDate(customerLimit.getLimitExpiryDate());
        limitReq.setRist_customer_group(secondLevel.getCustomerGroup());
        List<CmLimitAdjustLog> adjusts =
                cmLimitAdjustLogs.stream()
                        .filter(adjust -> Objects.requireNonNull(DateUtils.parseDate(adjust.getUpdateTime())).compareTo(DateUtils.parseDate(DateUtils.addMonth(today,3))) >= 0)
                        .collect(Collectors.toList());
        String adjustLeast3M = "0";
        if (CollectionUtils.isNotEmpty(adjusts)) {
            adjustLeast3M = "1";
        }
        // 1.是 0.否
        limitReq.setLatset3mte(adjustLeast3M);
        // 近三个月使用金额
        String loanAmount = extAmLoanAccountInfoMapper.sumLoanAmountByThreeMonth(tenantId, productId, customerId);
        BigDecimal averageuesedLateset3m = new BigDecimal(loanAmount).divide(BigDecimal.ONE.add(limitAmount), CommonContants.BIGDECIMAL_SCALE_4, BigDecimal.ROUND_HALF_UP)
                .divide(BigDecimal.ONE.add(new BigDecimal("3")), CommonContants.BIGDECIMAL_SCALE_4, BigDecimal.ROUND_HALF_UP);
        limitReq.setAverageuesed_lateset3m(averageuesedLateset3m.toString());
        Date limitEffectiveDate = customerLimit.getLimitEffectiveDate();
        // 额度效期内是否出现的最大逾期天数
        Integer maxOverdueDays = extAmDelinquencyInfoMapper.daysOverdueInExpiryDate(limitEffectiveDate, limitExpiryDate, customerId, tenantId);
        // 1.是 0.否
        limitReq.setDaysoverdue_3(maxOverdueDays > 3 ? "1" : "0");
        List<TlPaymentLog> tlPaymentLogs = extTlPaymentLogMapper.selectByCustomerIdProductsAndSumStatus(customerId, new String[]{TransBizConstant.PAYMENT_LOG_SUM_STATUS_S}, tenantId,
                Collections.singletonList(productId));
        // 非退款
        List<TlPaymentLog> successPayment = tlPaymentLogs.stream().filter(log -> !log.getPaymentType().equalsIgnoreCase(TransBizConstant.REPAYMENT_TYPE_REFUND)).collect(Collectors.toList());
        String successRepay1 = "0";
        int successRepayTimes = 0;
        if (CollectionUtils.isNotEmpty(successPayment)) {
            successRepay1 = "1";
            successRepayTimes = successPayment.size();
        }
        // 1.是 0.否
        limitReq.setSuccessrepay_1(successRepay1);
        limitReq.setSuccessrepay_2(successRepayTimes > 1 ? "1" : "0");
        limitReq.setSuccessrepay_times(successRepayTimes);
        List<CmCustomerContactInfo> contactList = extCmCustomerContactInfoMapper.selectByTenantIdAndCustomerId(tenantId, customerId);
        if (CollectionUtils.isNotEmpty(contactList)) {
            CmCustomerContactInfo contactInfo = contactList.get(0);
            limitReq.setContact_name_1st(contactInfo.getChineseName());
            limitReq.setContact_mobile_1st(contactInfo.getMobile());
        }
        limitReq.setProductId(productId);
        limitReq.setChannelNo(customerLimit.getChannel());
        limitReq.setUserId(secondLevel.getUserId());
        limitReq.setTenantId(tenantId);
        ApiResponse<LimitRenewResponse> limitRenewQueryRes = null;
        try {
            limitRenewQueryRes = iUserApiService.limitRenew(JsonUtils.toJSon(limitReq));
        } catch (Exception e) {
            e.printStackTrace();
            logger.warn("额度续签申请API失原因", e);
        }
        if (limitRenewQueryRes == null || TxnRespCode.SUCCESS.getCode() != limitRenewQueryRes.getCode()) {
            logger.warn("额度续签申请API失败,响应为空或者非成功码值");
        }
        logger.info("额度续签申请API响应信息：{}", JSONObject.toJSONString(limitRenewQueryRes));
        return customerLimit;
    }
}
